package com.bwie.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.bwie.common.core.utils.StringUtils;
import com.bwie.product.domain.po.SkuEsModel;
import com.bwie.product.domain.vo.SearchParam;
import com.bwie.product.domain.vo.SearchResult;
import com.bwie.product.service.ProductSearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ProductSearchServiceImpl implements ProductSearchService {
    @Autowired
    private RestHighLevelClient client;

    /**
     * 商品搜索
     * @param searchParam
     * @return
     */
    @Override
    public SearchResult productSearch(SearchParam searchParam) throws IOException {
        SearchRequest searchRequest = buildSearchRequest(searchParam);

        //2. 执行search
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchResult searchResult = analyerResponse(searchResponse, searchParam);

        return searchResult;
    }


    public SearchResult analyerResponse(SearchResponse searchResponse, SearchParam searchParam){

        SearchResult searchResult = new SearchResult();

        SearchHits hits = searchResponse.getHits();
        List<SkuEsModel> skuEsModelList = new ArrayList<>();

        for (SearchHit hit : hits.getHits()) {
            String sourceAsString = hit.getSourceAsString();
            SkuEsModel skuEsModel = JSON.parseObject(sourceAsString, SkuEsModel.class);

            // 处理高亮
            if (StringUtils.isNotBlank(searchParam.getKeyword())) {
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField skuTitleHighlightField = highlightFields.get("skuTitle");

                if (skuTitleHighlightField != null) {
                    Text[] fragments = skuTitleHighlightField.getFragments();
                    if (fragments != null && fragments.length > 0) {
                        skuEsModel.setSkuTitle(fragments[0].toString());
                    } else {
                        // 如果没有高亮片段，则使用原始标题
                        skuEsModel.setSkuTitle(skuEsModel.getSkuTitle()); // 或者设置默认值
                    }
                } else {
                    // 如果没有高亮信息，则使用原始标题
                    skuEsModel.setSkuTitle(skuEsModel.getSkuTitle()); // 或者设置默认值
                }
            }

            skuEsModelList.add(skuEsModel);
        }

        searchResult.setProducts(skuEsModelList);
        return searchResult;
    }


    public SearchRequest buildSearchRequest(SearchParam searchParam){

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if(StringUtils.isNotEmpty(searchParam.getKeyword())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle",searchParam.getKeyword()));
        }

        // 高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("skuTitle");
        highlightBuilder.preTags("<span style='color:skyblue;font-size:18px'>");
        highlightBuilder.postTags("</span>");

        searchSourceBuilder.highlighter(highlightBuilder);

        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("product");
        searchRequest.source(searchSourceBuilder);
        return searchRequest;
    }

}
